package com.portal.framework.util;

import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.Collection;
import java.util.Date;
import java.util.Iterator;
import java.util.Map;

import com.portal.framework.dao.annotation.SearchProp;
import com.portal.framework.dao.ISearchForm;

/**
 * 将对象的属性名和对应的值打印的工具类
 * 
 * @author 卢烁波
 * @date 2007-3-10
 */
public class ToStringUtil {

	/**
	 * 返回一个对象中所有定义了的属性的名字和值.每个属性的名字和值用逗号分割.
	 * 
	 * @param obj
	 * @return
	 */
	static public String reflectField(Object obj) {
		return reflectField(obj, true);
	}

	/**
	 * 返回一个对象中所有定义了的属性的名字和值.每个属性的名字和值用逗号分割.
	 * 
	 * @param obj
	 * @param appendClassName 是否添加类名
	 * @return
	 */
	static public String reflectField(Object obj, boolean appendClassName) {
		if (obj == null)
			return "null";
		return reflectField(obj, obj.getClass(), appendClassName);
	}

	static public String reflectField(Object obj, Class cls) {
		return reflectField(obj, cls, true);
	}

	static public String reflectField(Object obj, Class cls,
			boolean appendClassName) {
		StringBuffer buf = new StringBuffer(500);
		if (appendClassName)
			buf.append(ClassUtil.getShortName(cls)).append("[");
		if (!reflectField(buf, obj, cls, appendClassName)) {
			buf.append(obj);
		}
		if (appendClassName)
			buf.append("]");
		return buf.toString();
	}

	static private boolean reflectField(StringBuffer buf, Object obj,
			Class cls, boolean appendClassName) {
		if (obj == null)
			return false;
		try {
			boolean hasField = false;
			Field[] fs = cls.getDeclaredFields();
			for (Field f : fs) {
				if (Modifier.isFinal(f.getModifiers()))
					continue;
				hasField = true;
				boolean b = f.isAccessible();
				f.setAccessible(true);
				buf.append(f.getName());
				buf.append("=");
				Object v = f.get(obj);

				// array
				if (v != null && v.getClass().isArray()) {
					Object[] t = (Object[]) v;
					buf.append("[");
					for (int i = 0; i < t.length; i++) {
						if (i != 0)
							buf.append(",");
						buf.append(t[i]);
					}
					buf.append("]");
				}
				// collection
				else if (v != null && v instanceof Collection) {
					Collection c = (Collection) v;
					Iterator it = c.iterator();
					buf.append("[");
					while (it.hasNext()) {
						buf.append(it.next());
						if (it.hasNext())
							buf.append(",");
					}
					buf.append("]");
				}
				// map
				else if (v != null && v instanceof Map) {
					Map c = (Map) v;
					Iterator it = c.keySet().iterator();
					buf.append("[");
					while (it.hasNext()) {
						Object key = it.next();
						buf.append(key);
						buf.append("=");
						buf.append(c.get(key));
						if (it.hasNext())
							buf.append(",");
					}
					buf.append("]");
				} else {
					buf.append(f.get(obj));
				}
				buf.append(";");
				f.setAccessible(b);
			}
			Class p = cls.getSuperclass();
			if (p != null && p != Object.class) {
				return reflectField(buf, obj, p, false) || hasField;
			}
			return hasField;
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}

	public static String resflectSearchFormField(ISearchForm form) {
		if (form == null) {
			return "null";
		}
		Object value;
		StringBuilder sb = new StringBuilder();
		sb.append("[");
		Field[] fields = form.getClass().getDeclaredFields();
		for (Field f : fields) {
			if (f.getAnnotation(SearchProp.class) != null) {

				try {
					boolean old = f.isAccessible();
					f.setAccessible(true);
					value = f.get(form);
					f.setAccessible(old);
					if (value != null
							&& f.getType().isAssignableFrom(Date.class)) {
						value = DateTimeUtil.formatDateTime((Date) value);
					}
				} catch (IllegalAccessException e) {
					value = null;
					continue;
				}

				sb.append(f.getName());
				sb.append("=");
				sb.append(value);
				sb.append(",");
			}
		}

		sb.append("]");

		return sb.toString();
	}

}
